package com.voltmao.webpro.utils.wechat.utils.dto.pay;

import com.voltmao.webpro.utils.JsonUtil;
import com.voltmao.webpro.utils.PropertiesUtils;
import com.voltmao.webpro.utils.StringUtils;
import com.voltmao.webpro.utils.XMLUtils;
import com.voltmao.webpro.utils.wechat.core.Account;
import com.voltmao.webpro.utils.wechat.core.Signature;

import java.beans.IntrospectionException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by zhouyang on 2017/5/25.
 * 预下单对象
 */
public class PayMsg {
    private String appid;               //wxAppid
    private String mch_id;              //商户号
    private String nonce_str;           //随机字符串
    private String sign;                //签名
    private String trade_type = "JSAPI";  //交易类型
    private String out_trade_no;        //商户订单号
    private String openid;

    private String body;                //商品描述
    private int total_fee;              //金额
    private String spbill_create_ip;    //终端IP
    private String notify_url;          //异步接收微信支付结果通知的回调地址，通知url必须为外网可访问的url，不能携带参数。
    private String attach;              //附加数据 (可空) 长度127


    private Account account;

    /**
     * @param payDes      //支付描述
     * @param total_fee   //支付金额(分)
     * @param ip          //ip地址
     * @param backCellUrl //回调地址
     * @param otherParams //自定义参数
     */
    public PayMsg(String payDes, String openid, int total_fee, String ip, String backCellUrl, Map<String, Object> otherParams) {
        this.body = payDes;
        this.total_fee = total_fee;
        this.spbill_create_ip = ip;
        this.notify_url = backCellUrl;
        this.openid = openid;

        this.attach = StringUtils.getUrlParams(otherParams);
    }


    /**
     * 加载微信账户信息
     *
     * @param account
     */
    public void initAccount(Account account) {
        this.account = account;

        this.mch_id = account.getMerId();
        this.appid = account.getAppId();
        this.out_trade_no = StringUtils.uuid32();

        //TODO 需要签名算法
        this.nonce_str = StringUtils.uuid32();

        //加密
        try {
            this.signatureMD5(account.getPayKey());

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IntrospectionException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    /**
     * 签名
     *
     * @param payKey
     */
    private void signatureMD5(String payKey) throws UnsupportedEncodingException, NoSuchAlgorithmException, IllegalAccessException, IntrospectionException, InvocationTargetException {
        HashMap<String, Object> map = (HashMap<String, Object>) PropertiesUtils.objectToMap(this);
        this.sign = Signature.signatureMD5(map, payKey).toUpperCase();
    }

    /**
     * 转换为JSON形式
     *
     * @return
     */
    public String builderResult(String xml) {


        PayResult payResult = (PayResult) XMLUtils.xmlToObject(xml, PayResult.class, "xml");

        Map<String, Object> params = new HashMap();
        params.put("appId", this.getAppid());
        params.put("timeStamp", System.currentTimeMillis() + "");
        params.put("package", String.format("prepay_id=%s", payResult.getPrepay_id()));
        params.put("signType", "MD5");
        params.put("nonceStr", payResult.getNonce_str());
        params.put("paySign", Signature.signatureMD5(params, account.getPayKey()));                 // paySign的生成规则和Sign的生成规则一致

        params.put("sendUrl", this.getNotify_url());            // 付款成功后跳转的页面

//        String userAgent = request.getHeader("user-agent");
//        char agent = userAgent.charAt(userAgent.indexOf("MicroMessenger") + 15);
//        params.put("agent", new String(new char[] { agent }));// 微信版本号，用于前面提到的判断用户手机微信的版本是否是5.0以上版本。

        return JsonUtil.ObjectToJSON(params);
    }

    /**
     * 转换为XML形式
     *
     * @return
     */
    public String toXml() {
        return XMLUtils.parseXml(this);
    }


    public String getAppid() {
        return appid;
    }

    public void setAppid(String appid) {
        this.appid = appid;
    }

    public String getMch_id() {
        return mch_id;
    }

    public void setMch_id(String mch_id) {
        this.mch_id = mch_id;
    }

    public String getNonce_str() {
        return nonce_str;
    }

    public void setNonce_str(String nonce_str) {
        this.nonce_str = nonce_str;
    }

    public String getSign() {
        return sign;
    }

    public void setSign(String sign) {
        this.sign = sign;
    }

    public String getTrade_type() {
        return trade_type;
    }

    public void setTrade_type(String trade_type) {
        this.trade_type = trade_type;
    }

    public String getOut_trade_no() {
        return out_trade_no;
    }

    public void setOut_trade_no(String out_trade_no) {
        this.out_trade_no = out_trade_no;
    }

    public String getOpenid() {
        return openid;
    }

    public void setOpenid(String openid) {
        this.openid = openid;
    }

    public String getBody() {
        return body;
    }

    public void setBody(String body) {
        this.body = body;
    }

    public int getTotal_fee() {
        return total_fee;
    }

    public void setTotal_fee(int total_fee) {
        this.total_fee = total_fee;
    }

    public String getSpbill_create_ip() {
        return spbill_create_ip;
    }

    public void setSpbill_create_ip(String spbill_create_ip) {
        this.spbill_create_ip = spbill_create_ip;
    }

    public String getNotify_url() {
        return notify_url;
    }

    public void setNotify_url(String notify_url) {
        this.notify_url = notify_url;
    }

    public String getAttach() {
        return attach;
    }

    public void setAttach(String attach) {
        this.attach = attach;
    }
}
